﻿using System;
using System.Collections.Generic;
using System.Text;
using Crochet.Configuration;

namespace Crochet.Core.Policy
{
	public class ExecutionPolicyFactory
	{
		private static ExecutionPolicyFactory epfInstance;

		public static ExecutionPolicyFactory Instance
		{
			get
			{
				if (epfInstance == null)
				{
					lock (typeof(ExecutionPolicyFactory))
					{
						if (epfInstance == null)
						{
							epfInstance = new ExecutionPolicyFactory();
						}
					}
				}

				return epfInstance;
			}
		}/*

		public IExecutionPolicy Create(string sSchedulerName, ExecutionPolicyType eptExecutionPolicyType, SchedulerDelegate sdSchedulerDelegate)
		{
			return Create(sSchedulerName, eptExecutionPolicyType, sdSchedulerDelegate, null);
		}

		public IExecutionPolicy Create(string sSchedulerName, ExecutionPolicyType eptExecutionPolicyType, SchedulerDelegate sdSchedulerDelegate, ExceptionHandlerDelegate ehdExceptionHandlerDelegate)
		{
			return Create(sRootScheduler, eptExecutionPolicyType, sdSchedulerDelegate, ehdExceptionHandlerDelegate, GetParams(eptExecutionPolicyType, sPolicyName));
		}*/

		public IExecutionPolicy Create(string sExecutionPolicyName, SchedulerDelegate sdSchedulerDelegate)
		{
			return Create(sExecutionPolicyName, sdSchedulerDelegate, null);
		}

		public IExecutionPolicy Create(string sExecutionPolicyName, SchedulerDelegate sdSchedulerDelegate, ExceptionHandlerDelegate ehdExceptionHandlerDelegate)
		{
			object[]					oaParams						= null;
			IExecutionPolicy			epExecutionPolicy				= null;
			CrochetConfigurationElement	cceCrochetConfigurationElement	= CrochetConfiguration.Instance.GetPolicyElement(sExecutionPolicyName);

			if (cceCrochetConfigurationElement != null)
			{
				oaParams = cceCrochetConfigurationElement.GetAttributes();
			}

			if (cceCrochetConfigurationElement is RetryOnExceptionElement)
			{
				epExecutionPolicy = new RetryOnExceptionExecutionPolicy(null, sdSchedulerDelegate, ehdExceptionHandlerDelegate, (int)oaParams[1], (int)oaParams[2], (bool)oaParams[3]);
			}
			else if (cceCrochetConfigurationElement is RescheduleOnExceptionElement)
			{
				epExecutionPolicy = new RescheduleOnExceptionExecutionPolicy(null, sdSchedulerDelegate, ehdExceptionHandlerDelegate, (int)oaParams[1], (int)oaParams[2], (bool)oaParams[3]);
			}
			else
			{
				epExecutionPolicy = new DefaultExecutionPolicy(null, sdSchedulerDelegate, ehdExceptionHandlerDelegate);
			}

			return epExecutionPolicy;
		}

		public object[] GetParams(string sName)
		{
			object[] oParams = null;

			if ("RetryOnException".Equals(sName))
			{
				oParams = CrochetConfiguration.Instance.RetryOnExceptionPolicies.GetAttributes(sName);
			}
			else if ("RescheduleOnException".Equals(sName))
			{
				oParams = CrochetConfiguration.Instance.RescheduleOnExceptionPolicies.GetAttributes(sName);
			}

			return oParams;
		}
	}
}
